#include <stdio.h>
// функція, яка буде виконуватись на пристрої 
__global__ void VecAdd(float* A, float* B, float* C, int N)
{
    int i = blockDim.x * blockIdx.x + threadIdx.x;
    if (i < N)
        C[i] = A[i] + B[i];
}
            
// хост-частина
int main()
{
    int i, N = 1024;
    size_t size = N * sizeof(float);

    // Виділення пам’яті на хості для векторів h_A, h_B і h_C
    float* h_A = (float*)malloc(size);
    float* h_B = (float*)malloc(size);
    float* h_C = (float*)malloc(size);

    // ініціалізація векторів
    
for(i=0;i<N;i++)
{
h_A[i]=1.1f;
h_B[i]=2.2f;
}

    // виділення пам’яті на пристрої
    float* d_A;
    cudaMalloc(&d_A, size);
    float* d_B;
    cudaMalloc(&d_B, size);
    float* d_C;
    cudaMalloc(&d_C, size);

    // Копіювання векторів з хост-пам’яті у пам’ять пристрою
    cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
    cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);

    // Виконання ядра
    int threadsPerBlock = 256; // кількість потоків у блоці
    int blocksPerGrid =(N + threadsPerBlock - 1) / threadsPerBlock; // кількість блоків у сітці
    VecAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, N);

    // Копіювання вектору h_C, який містить результат з пам’яті пристрою у хост-пам’ять
    cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);
for(i=0;i<N;i++)
printf(" %f   %f   %f \n",h_A[i],h_B[i],h_C[i]);
    // Вивільнення пам’яті на пристрої
    cudaFree(d_A);
    cudaFree(d_B);
    cudaFree(d_C);
            
    // Вивільнення пам’яті на хості
    free(h_A);
    free(h_B);
    free(h_C);
    return 0;
}
